package com.gloaba.common.mongo.service;


import cn.hutool.core.map.MapUtil;
import com.gloaba.common.core.utils.JsonUtils;
import com.mongodb.client.result.UpdateResult;
//import com.gloaba.common.core.web.page.TableDataInfo;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.BasicUpdate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Component
public class MongoServiceImpl<T> extends BaseMongoDocumentService implements IMongoService<T> {

    @Override
    public void saveEntity(T t) {
        mongoTemplate.save(t);
    }

    @Override
    public void saveEntity(T t,String collectionName) {
        mongoTemplate.save(t,collectionName);
    }

    @Override
    public long updateEntityById(T t, String id) {
        Type superclass = getClass().getGenericSuperclass();
        Type supertype = ((ParameterizedType) superclass).getActualTypeArguments()[0];
        Class<T> clazz = (Class<T>) supertype;
        Query query = new Query(Criteria.where("_id").is(id));

        BasicUpdate update= new BasicUpdate(JsonUtils.toJsonString(t));

        //更新查询返回结果集的第一条
        UpdateResult result = mongoTemplate.updateFirst(query, update, clazz);
        if(result!=null) {
            return result.getMatchedCount();
        } else {
            return 0;
        }
    }

    @Override
    public long updateEntityByCondition(T t, Map<String,Object> condition){
        Type superclass = getClass().getGenericSuperclass();
        Type supertype = ((ParameterizedType) superclass).getActualTypeArguments()[0];
        Class<T> clazz = (Class<T>) supertype;
        if(MapUtil.isEmpty(condition)){
            return 0;
        }
        Query query = new Query();
        for (Map.Entry<String, Object> entry : condition.entrySet()) {
            query.addCriteria(Criteria.where(entry.getKey()).is(entry.getValue()));
        }

        BasicUpdate update= new BasicUpdate(JsonUtils.toJsonString(t));

        //更新查询返回结果集的第一条
        UpdateResult result = mongoTemplate.updateFirst(query, update, clazz);
        if(result!=null) {
            return result.getMatchedCount();
        } else {
            return 0;
        }
    }

    @Override
    public long updateEntity(T t, Query query) {
        Type superclass = getClass().getGenericSuperclass();
        Type supertype = ((ParameterizedType) superclass).getActualTypeArguments()[0];
        Class<T> clazz = (Class<T>) supertype;
        BasicUpdate update= new BasicUpdate(JsonUtils.toJsonString(t));

        //更新查询返回结果集的第一条
        UpdateResult result = mongoTemplate.updateFirst(query, update, clazz);
        if(result!=null) {
            return result.getMatchedCount();
        } else {
            return 0;
        }
    }

    @Override
    public void deleteEntityById(Long id) {
        Type superclass = getClass().getGenericSuperclass();
        Type supertype = ((ParameterizedType) superclass).getActualTypeArguments()[0];
        Class<T> clazz = (Class<T>) supertype;
        Query query = new Query(Criteria.where("_id").is(id));
        mongoTemplate.remove(query, clazz);
    }

    @Override
    public List<T> findAll() {
        Type superclass = getClass().getGenericSuperclass();
        Type supertype = ((ParameterizedType) superclass).getActualTypeArguments()[0];
        Class<T> clazz = (Class<T>) supertype;
        return mongoTemplate.findAll(clazz);
    }

    @Override
    public <T> List<T> findAggregateList(String collectionName, Aggregation aggregation, Class<T> clazz) {
        AggregationResults<T> aggregate = this.mongoTemplate.aggregate(aggregation, collectionName, clazz);
        List<T> customerDetails = aggregate.getMappedResults();
        return customerDetails;
    }

//    @Override
//    public TableDataInfo<T> findList(Query query, Integer pageIndex, Integer pageSize) {
//        TableDataInfo<T> tableDataInfo = new TableDataInfo<>();
//        pageIndex = Optional.ofNullable(pageIndex).orElse(1);
//        pageSize = Optional.ofNullable(pageSize).orElse(20);
//        Type superclass = getClass().getGenericSuperclass();
//        Type supertype = ((ParameterizedType) superclass).getActualTypeArguments()[0];
//        Class<T> clazz = (Class<T>) supertype;
//        // 查询数量
//        tableDataInfo.setTotal(mongoTemplate.count(query, clazz));
//
//        //分页
////        query.with(Sort.by(Sort.Direction.DESC, "age"));
//        query.skip((pageIndex -  1) * pageSize).limit(pageSize);
//        tableDataInfo.setList(mongoTemplate.find(query, clazz));
//        return tableDataInfo;
//    }

}

